package android.slc.module.component.image_loader;


import android.slc.box.commonlibrary.compat.SlcPathUtils;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import javafx.application.Platform;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.apache.commons.collections4.IterableUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class ImageLoader {

    private final String url;
    private final String placeholder;
    private final WeakReference<ImageView> imageViewWR;
    private final int retryCount;
    private int currentRetryCount;
    private final List<TransformImage> transformImageList;
    private final List<TransformImageView> transformImageViewList;

    public ImageLoader(String url, String placeholder, ImageView imageView, int retryCount, List<TransformImage> transformImageList, List<TransformImageView> transformImageViewList) {
        this.url = url;
        this.placeholder = placeholder;
        this.imageViewWR = new WeakReference<>(imageView);
        this.retryCount = retryCount;
        this.transformImageList = transformImageList;
        this.transformImageViewList = transformImageViewList;
        startUp();
    }

    private ImageView getImageView() {
        return imageViewWR.get();
    }

    protected void startUp() {
        if (getImageView() == null) {
            return;
        }
        if (StringUtils.isNotEmpty(this.placeholder)) {
            loadImagePlaceholder(new Image(this.placeholder));
        }
        if (HttpUtil.isHttp(url) || HttpUtil.isHttps(url)) {
            loadWithNet();
        } else if (FileUtil.isFile(url)) {
            loadWithFile();
        } else {
            loadWithPath(url);
        }
    }

    private void loadWithNet() {
        ImageLoaderExecutorService.getInstance().getThreadPoolExecutor().execute(new Runnable() {
            @Override
            public void run() {
                if (getImageView() == null) {
                    return;
                }
                //获取文件
                File savePath = FileUtil.file(ImageLoaderConfig.getInstance().getSavePath());
                String fileName = FileNameUtil.getName(URLUtil.decode(url));
                File imageFile = new File(savePath, fileName);
                if (!imageFile.exists()) {
                    try {
                        imageFile = HttpUtil.downloadFileFromUrl(url, imageFile);
                    } catch (Exception e) {
                        handlerError(imageFile);
                        return;
                    }
                }
                //加载图片
                String path = SlcPathUtils.path2Url(imageFile);
                Image pathImage = new Image(path);
                if (pathImage.isError()) {
                    handlerError(imageFile);
                    return;
                }
                //通知主线程加载文件
                Platform.runLater(() -> {
                    if (getImageView() == null) {
                        return;
                    }
                    transformImage(pathImage);
                });
            }
        });
        /*ImageLoadExecutorService.getInstance().getThreadPoolExecutor().execute(new Task);
        Single.just(url)
                .map(url -> {
                    File savePath = AppPathUtils.createAppCacheFile("file");
                    String fileName = FileNameUtil.getName(URLUtil.decode(url));
                    File imageFile = new File(savePath, fileName);
                    if (imageFile.exists()) {
                        return imageFile;
                    } else {
                        return HttpUtil.downloadFileFromUrl(url, imageFile);
                    }
                })
                .compose(SlcRxJavaUtils.applyOsAndroidSchedulers())
                .subscribe(new SimpleSingleObserver<File>() {
                    @Override
                    public void onSuccess(@NotNull File file) {
                        super.onSuccess(file);
                        String path = SlcPathUtils.path2Url(file);
                        Image pathImage = new Image(path);
                        if (pathImage.isError()) {
                            handlerError(file);
                            return;
                        }
                        transformImage(pathImage);
                    }

                    @Override
                    public void onError(@NotNull Throwable e) {
                        super.onError(e);
                        handlerError(null);
                    }
                });*/
    }

    private void loadWithFile() {
        ImageLoaderExecutorService.getInstance().getThreadPoolExecutor().execute(new Runnable() {
            @Override
            public void run() {
                if (getImageView() == null) {
                    return;
                }
                Image pathImage = new Image(SlcPathUtils.path2Url(url));
                if (pathImage.isError()) {
                    //TODO 加载文件错误则什么否不处理
                    return;
                }
                //通知主线程加载文件
                Platform.runLater(() -> {
                    if (getImageView() == null) {
                        return;
                    }
                    transformImage(pathImage);
                });
            }
        });
    }

    private void loadWithPath(String path) {
        transformImage(new Image(path));
    }

    /**
     * 转换
     *
     * @param image
     */
    private void transformImage(Image image) {
        if (IterableUtils.isEmpty(transformImageList)) {
            loadImage(image);
            return;
        }
        //转换
        for (TransformImage transformImage : transformImageList) {
            image = transformImage.onTransform(image);
        }
        loadImage(image);
    }

    private void loadImage(Image image) {
        if (getImageView() == null) {
            return;
        }
        if (Platform.isFxApplicationThread()) {
            getImageView().setImage(image);
            transformImageView();
        } else {
            Platform.runLater(() -> {
                if (getImageView() == null) {
                    return;
                }
                getImageView().setImage(image);
                transformImageView();
            });
        }
    }

    private void transformImageView() {
        if (IterableUtils.isEmpty(transformImageViewList)) {
            return;
        }
        //转换
        ImageView imageView = this.getImageView();
        for (TransformImageView transformImageView : transformImageViewList) {
            imageView = transformImageView.onTransform(imageView);
        }
    }

    private void handlerError(File imageFile) {
        //必删除文件才能重新下载
        if (imageFile != null) {
            try {
                FileUtil.del(imageFile);
            } catch (Exception ignored) {
            }
        }
        tryRetry();
    }

    private synchronized void tryRetry() {
        ImageLoader.this.currentRetryCount++;
        if (ImageLoader.this.currentRetryCount > ImageLoader.this.retryCount) {
            return;
        }
        Platform.runLater(this::loadWithNet);
    }

    private void loadImagePlaceholder(Image image) {
        if (getImageView() == null) {
            return;
        }
        if (Platform.isFxApplicationThread()) {
            getImageView().setImage(image);
        } else {
            Platform.runLater(() -> {
                if (getImageView() == null) {
                    return;
                }
                getImageView().setImage(image);
            });
        }
    }

    public interface TransformImage {
        Image onTransform(Image image);
    }

    public interface TransformImageView {
        ImageView onTransform(ImageView imageView);
    }

    public static Builder load(String url) {
        return new Builder().load(url);
    }

    public static class Builder {
        private String url;
        private String placeholder;
        private ImageView imageView;
        private int retryCount = 3;
        private final List<TransformImage> transformImageList = new ArrayList<>();
        private final List<TransformImageView> transformImageViewList = new ArrayList<>();

        public Builder load(String url) {
            this.url = url;
            return this;
        }

        public Builder setPlaceholder(String placeholder) {
            this.placeholder = placeholder;
            return this;
        }

        public Builder setImageView(ImageView imageView) {
            this.imageView = imageView;
            return this;
        }

        public Builder setRetryCount(int retryCount) {
            this.retryCount = retryCount;
            return this;
        }

        public Builder addTransformImage(TransformImage transformImage) {
            this.transformImageList.add(transformImage);
            return this;
        }

        public Builder addTransformImageView(TransformImageView transformImageView) {
            this.transformImageViewList.add(transformImageView);
            return this;
        }

        public ImageLoader into(ImageView imageView) {
            setImageView(imageView);
            return into();
        }

        public ImageLoader into() {
            return new ImageLoader(url, placeholder, imageView, retryCount, transformImageList, this.transformImageViewList);
        }
    }
}
